Error Alert and Summarizer

工作流概述

这是一个包含13个节点的复杂工作流,主要用于自动化处理各种任务。

工作流源代码

下载
{
  "id": "3b1q6ZJTxeONrpUV",
  "meta": {
    "instanceId": ""
  },
  "name": "Error Alert and Summarizer",
  "tags": [],
  "nodes": [
    {
      "id": "d29a5b06-1609-416f-bc74-0274d3321019",
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -600,
        -40
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "a71d3052-a89b-4e8e-baee-7fe245575f42",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        528,
        180
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "gpt-4o"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "786",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "e71dee7b-4dfd-49ab-8939-f3808ee112d7",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        648,
        180
      ],
      "parameters": {
        "jsonSchemaExample": "{
\"diagnosis\":\"\",
\"cause\":\"\",
\"resolution\":\"\"
}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "3611e9e8-f677-49c4-b06c-fa6c28f43930",
      "name": "SET EMAIL",
      "type": "n8n-nodes-base.set",
      "position": [
        -380,
        -40
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "45e1443a-fb44-42f8-96ad-423197c7265b",
              "name": "TO",
              "type": "string",
              "value": "myemail@myemail.com"
            },
            {
              "id": "968b05dc-f476-4e13-8166-e62005d0f936",
              "name": "CC",
              "type": "string",
              "value": "theiremail@theiremail.com"
            },
            {
              "id": "570663c5-29c0-44fb-9992-908b7cca8136",
              "name": "BCC",
              "type": "string",
              "value": "theiremail@theiremail.com"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3676f72e-d06d-44f8-be35-19efe09a257e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -450,
        -260
      ],
      "parameters": {
        "color": 3,
        "height": 380,
        "content": "# SET YOUR EMAILS"
      },
      "typeVersion": 1
    },
    {
      "id": "f0b08a20-6ecc-4487-9a0a-30be07cc0cbb",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        -260
      ],
      "parameters": {
        "color": 3,
        "width": 280,
        "height": 380,
        "content": "# Enable/Disable Manual Executions"
      },
      "typeVersion": 1
    },
    {
      "id": "b35cd2a6-5f22-4e06-9bb0-880855c423a8",
      "name": "Remove Manual Exec",
      "type": "n8n-nodes-base.if",
      "position": [
        60,
        -40
      ],
      "parameters": {
        "options": {
          "ignoreCase": true
        },
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "9b2f3ff3-db9c-406b-a97f-37620dc5fab9",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.mode }}",
              "rightValue": "manual"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2a33b02a-78f1-4243-ba7d-f217ea4d1895",
      "name": "Get Failed Exec",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -160,
        -40
      ],
      "parameters": {
        "options": {
          "activeWorkflows": true
        },
        "resource": "execution",
        "operation": "get",
        "executionId": "={{ $('Error Trigger').item.json.execution.id }}",
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "786",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b36ccbf9-4e47-44fc-aed3-424b6f121329",
      "name": "Extract Error Details",
      "type": "n8n-nodes-base.code",
      "position": [
        280,
        -40
      ],
      "parameters": {
        "jsCode": "// 1) Grab your full execution JSON
const exec = items[0].json;

// 2) Build execution‐level metadata
const meta = {
  executionId:    exec.id,
  finished:       exec.finished,
  mode:           exec.mode,
  status:         exec.status,
  createdAt:      exec.createdAt,
  startedAt:      exec.startedAt,
  stoppedAt:      exec.stoppedAt,
  deletedAt:      exec.deletedAt,
  workflowId:     exec.workflowId,
  workflowName:   exec.workflowData?.name,
  retryOf:        exec.retryOf,
  retrySuccessId: exec.retrySuccessId,
};

// 3) Identify trigger node name from startData
const runNodeFilter = exec.data?.startData?.runNodeFilter || [];
const triggerNodeName = runNodeFilter[0] || null;

// 4) Grab the raw trigger runData
const runData = exec.data?.resultData?.runData || {};
const triggerRuns = triggerNodeName ? (runData[triggerNodeName] || []) : [];

// 5) Extract the JSON payload from the first run of the trigger
let triggerPayload = {};
if (triggerRuns.length && triggerRuns[0].data?.main?.[0]?.[0]?.json) {
  triggerPayload = triggerRuns[0].data.main[0][0].json;
}

// 6) Merge trigger info into meta
meta.triggerNodeName = triggerNodeName;
meta.triggerPayload  = triggerPayload;

// 7) Now scan for all node errors, **excluding** any nodeName that contains “SERP”
const allErrors = [];
for (const [nodeName, runs] of Object.entries(runData)) {
  // Skip any of the SERP nodes
  if (nodeName.includes('SERP')) continue;

  runs.forEach(run => {
    if (run.executionStatus === 'error') {
      const err     = run.error || exec.data.resultData.error || {};
      const nodeDef = err.node || run.node || {};

      allErrors.push({
        ...meta,                    // exec + trigger metadata

        nodeName,
        nodeId:        nodeDef.id,
        nodeType:      nodeDef.type,
        nodeLabel:     nodeDef.name,

        startTime:     run.startTime,
        executionTime: run.executionTime,
        source:        run.source,

        errorName:        err.name,
        errorMessage:     err.message,
        errorDescription: err.description,
        httpCode:         err.httpCode,
        messages:         err.messages,
        context:          err.context,
        stack:            err.stack,

        parameters:       nodeDef.parameters,
        credentials:      nodeDef.credentials,
      });
    }
  });
}

// 8) Return results
if (!allErrors.length) {
  return [{ json: { message: '✅ No (non‑SERP) errors found in this execution.' } }];
}
return allErrors.map(e => ({ json: e }));
"
      },
      "typeVersion": 2
    },
    {
      "id": "a26fb0c8-99eb-466d-b201-89c402fa1af4",
      "name": "Error Solver Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        500,
        -40
      ],
      "parameters": {
        "text": "=Can you please help me with this error that occured in my n8n workflow? {{ JSON.stringify($json) }}",
        "options": {
          "systemMessage": "You are an seasoned n8n expert with specializations in managing n8n instances and workflows. The user will provide a detailed error json object and your goal is to review, analyze and understand the error and using your expertise diagnose the error and provide a detailed report to the user with your diagnosis, cause and resolution so the user understands and can immediately fix the issue."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.8
    },
    {
      "id": "8cfd7229-3ff1-4ba1-a67d-caa21be8064f",
      "name": "Set Diagnosis Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        876,
        -40
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "fac5fbee-d63d-4148-b047-5ed5af4f2574",
              "name": "error.diagnosis",
              "type": "string",
              "value": "={{ $json.output.diagnosis }}"
            },
            {
              "id": "ece9388d-f667-4984-a143-7241f622fe76",
              "name": "error.cause",
              "type": "string",
              "value": "={{ $json.output.cause }}"
            },
            {
              "id": "acb6b34a-a651-42fc-a44a-331b2e0d745c",
              "name": "error.resolution",
              "type": "string",
              "value": "={{ $json.output.resolution }}"
            },
            {
              "id": "c765754b-d6d5-4592-ac3f-99a350bc3c19",
              "name": "error.workflowName",
              "type": "string",
              "value": "={{ $('Extract Error Details').item.json.workflowName }}"
            },
            {
              "id": "dabebc62-3e0c-4d22-afbf-54ba66a912fb",
              "name": "error.workflowId",
              "type": "string",
              "value": "={{ $('Extract Error Details').item.json.workflowId }}"
            },
            {
              "id": "6ab19800-9a0f-439f-bf62-7a7afc5bf958",
              "name": "workflowLink",
              "type": "string",
              "value": "={{ $execution.resumeUrl.split('/').slice(0, 3).join('/') }}/workflow/{{ $('Extract Error Details').item.json.workflowId }}"
            },
            {
              "id": "29daaea5-052b-46d4-8192-141db159bff2",
              "name": "error.executionId",
              "type": "string",
              "value": "={{ $('Extract Error Details').item.json.executionId }}"
            },
            {
              "id": "9e4e553c-c82b-41ec-8ee2-14162cdc3bd8",
              "name": "executionLink",
              "type": "string",
              "value": "={{ $execution.resumeUrl.split('/').slice(0, 3).join('/') }}/workflow/{{ $('Extract Error Details').item.json.workflowId }}/executions/{{ $('Extract Error Details').item.json.executionId }}"
            },
            {
              "id": "7269ea9f-ed49-46cd-89f2-d4a467da529d",
              "name": "error.finished",
              "type": "boolean",
              "value": "={{ $('Extract Error Details').item.json.finished }}"
            },
            {
              "id": "29a6e6d2-5058-4dd9-b2f9-3980a6a9073a",
              "name": "error.startedAt",
              "type": "string",
              "value": "={{ $('Extract Error Details').item.json.startedAt }}"
            },
            {
              "id": "a0ad0e13-5a6e-48db-9a80-74c09434de7f",
              "name": "error.nodeName",
              "type": "string",
              "value": "={{ $('Extract Error Details').item.json.nodeName }}"
            },
            {
              "id": "6c1001d4-a581-4520-9f16-a2c7cf0e1f84",
              "name": "error.previousNode",
              "type": "string",
              "value": "={{ $('Extract Error Details').item.json.source[0].previousNode }}"
            },
            {
              "id": "8c3402ca-3f15-44ae-9b96-ea37c174334c",
              "name": "rawJson",
              "type": "string",
              "value": "={{ JSON.stringify($('Extract Error Details').item.json) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "9e95edf0-b2f1-443b-9ac4-3e3b3311cad5",
      "name": "Send Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1316,
        -40
      ],
      "webhookId": "2f253c1f-36c3-4d58-ba2f-3a50bb78f188",
      "parameters": {
        "sendTo": "={{ $('SET EMAIL').item.json.TO }}",
        "message": "={{ $json.html }}",
        "options": {
          "ccList": "={{ $('SET EMAIL').item.json.CC }}",
          "bccList": "={{ $('SET EMAIL').item.json.BCC }}",
          "appendAttribution": true
        },
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "786",
          "name": "Gmail account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "1705ee42-0be4-41a2-8ff9-f6963eef7382",
      "name": "Generate Email",
      "type": "n8n-nodes-base.code",
      "position": [
        1100,
        -40
      ],
      "parameters": {
        "jsCode": "// 1. Pull in your error payload
const rawInput = items[0].json;
const parsed = typeof rawInput === 'string' ? JSON.parse(rawInput) : rawInput;
const errorArray = Array.isArray(parsed) ? parsed : [parsed];

// 2. Build HTML & Markdown sections
let htmlSections = '';


for (const errObj of errorArray) {
  const {
    error: {
      workflowName,
      executionId,
      nodeName,
      previousNode,
      diagnosis,
      cause,
      resolution,
      startedAt,
    },
    workflowLink,
    executionLink,
  } = errObj;

  // HTML block
  htmlSections += `
    <div style=\"border:1px solid #ddd;border-radius:4px;padding:16px;margin-bottom:20px;background:#fafafa;\">
      <h3 style=\"margin:0 0 10px;color:#c0392b;font-family:Arial,sans-serif;\">
        🛑 ${workflowName} — Error in node: ${nodeName}
      </h3>
      <p style=\"margin:4px 0;font-family:Arial,sans-serif;\">
        <strong>Workflow:</strong> 
        <a href=\"${workflowLink}\" style=\"color:#2980b9;text-decoration:none;\">
          ${workflowName}
        </a><br/>
        <strong>Execution:</strong> 
        <a href=\"${executionLink}\" style=\"color:#2980b9;text-decoration:none;\">
          #${executionId}
        </a><br/>
        <strong>Previous Node:</strong> ${previousNode}<br/>
        <strong>Started At:</strong> ${new Date(startedAt).toLocaleString('en-US', { timeZone: 'America/New_York' })}
      </p>
      <hr style=\"border:none;border-top:1px solid #ccc;margin:12px 0;\"/>
      <h4 style=\"margin:0 0 6px;color:#e67e22;font-family:Arial,sans-serif;\">🔍 Diagnosis</h4>
      <p style=\"margin:4px 0 12px;font-family:Arial,sans-serif;\">${diagnosis}</p>
      <h4 style=\"margin:0 0 6px;color:#e67e22;font-family:Arial,sans-serif;\">⚙️ Cause</h4>
      <p style=\"margin:4px 0 12px;font-family:Arial,sans-serif;\">${cause}</p>
      <h4 style=\"margin:0 0 6px;color:#e67e22;font-family:Arial,sans-serif;\">✅ Resolution</h4>
      <p style=\"white-space:pre-wrap;margin:4px 0;font-family:Arial,sans-serif;\">${resolution}</p>
    </div>`;

// 3. Wrap up
const html = `
  <div style=\"font-family:Arial,sans-serif;color:#333;background:#fff;padding:20px;\">
    <h2 style=\"margin-top:0;color:#2c3e50;\">Automated Error Report</h2>
    ${htmlSections}
     <p style=\"font-size:12px;color:#777;font-family:Arial,sans-serif;\">
  This message was generated automatically by 
  <a href=\"https://realsimple.dev\" style=\"color:#777;text-decoration:none;\"><b>Real Simple Solutions</b></a>.
</p>
<div style=\"background:#f0f4ff;padding:8px 12px;margin-top:6px;border-radius:6px;font-size:12px;font-family:Arial,sans-serif;\">
  ✨ <strong>Want more n8n AI automation templates?</strong><br>
  Check out our full collection on 
  <a href=\"https://joeper.es/4jXyRub\" style=\"color:#0066cc;text-decoration:none;\"><b>Gumroad</b></a>.
</div>
  </div>
`;

// 4. Return all three
return [
  {
    json: {
      subject: `🚨 n8n Error: ${errorArray[0].error.workflowName} (#${errorArray[0].error.executionId})`,
      html
    },
  },
];
"
      },
      "typeVersion": 2
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "be484a20-26cd-4df4-a993-f7d01c2956e6",
  "connections": {
    "SET EMAIL": {
      "main": [
        [
          {
            "node": "Get Failed Exec",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Trigger": {
      "main": [
        [
          {
            "node": "SET EMAIL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Email": {
      "main": [
        [
          {
            "node": "Send Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Failed Exec": {
      "main": [
        [
          {
            "node": "Remove Manual Exec",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Error Solver Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Error Solver Agent": {
      "main": [
        [
          {
            "node": "Set Diagnosis Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Manual Exec": {
      "main": [
        [
          {
            "node": "Extract Error Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Diagnosis Fields": {
      "main": [
        [
          {
            "node": "Generate Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Error Details": {
      "main": [
        [
          {
            "node": "Error Solver Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Error Solver Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}

功能特点

  • 自动检测新邮件
  • AI智能内容分析
  • 自定义分类规则
  • 批量处理能力
  • 详细的处理日志

技术分析

节点类型及作用

  • Errortrigger
  • @N8N/N8N Nodes Langchain.Lmchatopenai
  • @N8N/N8N Nodes Langchain.Outputparserstructured
  • Set
  • Stickynote

复杂度评估

配置难度:
★★★★☆
维护难度:
★★☆☆☆
扩展性:
★★★★☆

实施指南

前置条件

  • 有效的Gmail账户
  • n8n平台访问权限
  • Google API凭证
  • AI分类服务订阅

配置步骤

  1. 在n8n中导入工作流JSON文件
  2. 配置Gmail节点的认证信息
  3. 设置AI分类器的API密钥
  4. 自定义分类规则和标签映射
  5. 测试工作流执行
  6. 配置定时触发器(可选)

关键参数

参数名称 默认值 说明
maxEmails 50 单次处理的最大邮件数量
confidenceThreshold 0.8 分类置信度阈值
autoLabel true 是否自动添加标签

最佳实践

优化建议

  • 定期更新AI分类模型以提高准确性
  • 根据邮件量调整处理批次大小
  • 设置合理的分类置信度阈值
  • 定期清理过期的分类规则

安全注意事项

  • 妥善保管API密钥和认证信息
  • 限制工作流的访问权限
  • 定期审查处理日志
  • 启用双因素认证保护Gmail账户

性能优化

  • 使用增量处理减少重复工作
  • 缓存频繁访问的数据
  • 并行处理多个邮件分类任务
  • 监控系统资源使用情况

故障排除

常见问题

邮件未被正确分类

检查AI分类器的置信度阈值设置,适当降低阈值或更新训练数据。

Gmail认证失败

确认Google API凭证有效且具有正确的权限范围,重新进行OAuth授权。

调试技巧

  • 启用详细日志记录查看每个步骤的执行情况
  • 使用测试邮件验证分类逻辑
  • 检查网络连接和API服务状态
  • 逐步执行工作流定位问题节点

错误处理

工作流包含以下错误处理机制:

  • 网络超时自动重试(最多3次)
  • API错误记录和告警
  • 处理失败邮件的隔离机制
  • 异常情况下的回滚操作